package com.icesoft.core.web.suppose.safehttp.filter.impl;

import com.icesoft.core.common.helper.Resp;
import com.icesoft.core.web.helper.ResponseUtils;
import com.icesoft.core.web.helper.http.SignUtil;
import com.icesoft.core.web.suppose.csrf.TimeUnitNonceStrFilter;
import com.icesoft.core.web.suppose.safehttp.SafeRequestConst;
import com.icesoft.core.web.suppose.safehttp.filter.HeadSafeRequestFilter;
import com.icesoft.core.web.suppose.safehttp.filter.ParamSafeRequestFilter;
import com.icesoft.core.web.suppose.safehttp.filter.SafeRequestCryptoService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.TreeMap;

@Component
@Slf4j
@AllArgsConstructor
public class SignFilter implements ParamSafeRequestFilter, HeadSafeRequestFilter {
    private final SafeRequestCryptoService safeRequestCryptoService;

    @Override
    public boolean paramFilter(HttpServletRequest request, HttpServletResponse response,
                               TreeMap<String, String> paramMap) {
        String paramSign = safeRequestCryptoService.getSign();
        log.trace("head sign:{}", paramSign);
        if (StringUtils.isBlank(paramSign)) {
            ResponseUtils.writeJson(response, Resp.error("签名sign为空"));
            return false;
        }
        String sign = SignUtil.sign(paramMap, TimeUnitNonceStrFilter.getTimeUnit(request),
                TimeUnitNonceStrFilter.getNonceStr(request));
        if (!paramSign.equalsIgnoreCase(sign)) {
            log.info("签名错误，服务器签名：{}，客户端签名：{}", sign, paramSign);
            ResponseUtils.writeJson(response, Resp.error("签名错误"));
            return false;
        }
        return true;
    }

    @Override
    public boolean headFilter(HttpServletRequest request, HttpServletResponse response) {
        String sign = request.getHeader(SafeRequestConst.HEAD_SIGN_PARAM_NAME);
        if (sign == null) {
            ResponseUtils.writeJson(response, Resp.error("签名sign为空"));
            return false;
        }
        String keyId = request.getHeader(SafeRequestConst.HEAD_KEY_ID_PARAM_NAME);
        if (keyId == null) {
            ResponseUtils.writeJson(response, Resp.error("密钥id为空"));
            return false;
        }
        safeRequestCryptoService.decryptSign(keyId, sign);
        return true;
    }
}
